﻿namespace Northwind.Web.App.Controllers.ApiControllers
{
    using System;
    using System.Linq;
    using System.Web.Http;
    using NRepository.Core;
    using NRepository.Core.Query;

    // Requires: NRepository.Core.3.2
    public class AccountsController : ApiController
    {
        private static readonly string[] _allowableSortBys = new[]
        {
            PropertyInfo<Account>.GetMemberName(p => p.MainPhoneNumber),
            PropertyInfo<Account>.GetMemberName(p => p.AccountNumber),
            PropertyInfo<Account>.GetMemberName(p => p.Name),
            PropertyInfo<Account>.GetMemberName(p => p.NickName),
        };

        private readonly IQueryRepository _queryRepository;

        public AccountsController(IQueryRepository queryRepository)
        {
            _queryRepository = queryRepository;
        }

        [ActionName("SearchAccounts")]
        public object GetSearchAccounts(
                string search = "",
                int page = 1,
                int pageSize = int.MaxValue,
                string sortBy = "Name",
                bool ascending = true)
        {
            var rowCountCallback = default(Func<int>);
            var results = _queryRepository.GetEntities<Account>(
                new MultipleTextSearchSpecificationStrategy<Account>(
                    search,
                    p => p.AccountNumber,
                    p => p.MainPhoneNumber,
                    p => p.Name,
                    p => p.NickName).OnCondition(!string.IsNullOrWhiteSpace(search)),
                new ConditionalQueryStrategy(_allowableSortBys.Contains(sortBy),
                    () => new OrderByQueryStrategy(sortBy).OnCondition(ascending),
                    () => new OrderByDescendingQueryStrategy(sortBy).OnCondition(!ascending)),
                new PagingQueryStrategy(page, pageSize, out rowCountCallback).OnCondition(_allowableSortBys.Contains(sortBy)));
    
            // use projection
            var accounts = results.Select(p => new
            {
                Name = p.Name,
            }).ToArray();

            return new
            {
                TotalCount = rowCountCallback(),
                Accounts = accounts,
            };
        }
    }
}
